package com.winapi.project.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.winapi.project.annotation.AuthCheck;
import com.winapi.project.common.BaseResponse;
import com.winapi.project.common.DeleteRequest;
import com.winapi.project.common.ErrorCode;
import com.winapi.project.common.ResultUtils;
import com.winapi.project.constant.CommonConstant;
import com.winapi.project.constant.UserConstant;
import com.winapi.project.exception.BusinessException;
import com.winapi.project.model.dto.interfaceinfo.InterfaceInfoQueryRequest;
import com.winapi.project.model.dto.interfaceinfo.InterfaceInfoUpdateRequest;
import com.winapi.project.model.dto.userinterfaceinfo.UpdateUserInterfaceInfoDTO;
import com.winapi.project.model.dto.userinterfaceinfo.UserInterfaceInfoAddRequest;
import com.winapi.project.model.vo.UserInterfaceInfoVO;
import com.winapi.project.service.InterfaceInfoChargeService;
import com.winapi.project.service.InterfaceInfoService;
import com.winapi.project.service.UserInterfaceInfoService;
import com.winapi.project.service.UserService;
import com.winapi.winapicommon.model.entity.InterfaceInfo;
import com.winapi.winapicommon.model.entity.InterfaceInfoCharge;
import com.winapi.winapicommon.model.entity.User;
import com.winapi.winapicommon.model.entity.UserInterfaceInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * 帖子接口
 *
 * @author 张莹莹
 * @from
 */
@RestController
@RequestMapping("/userInterfaceInfo")
@Slf4j

public class UserInterfaceInfoController {
    private static final String userInterfaceLog="用户接口模块-";
    @Resource
    private UserInterfaceInfoService userInterfaceInfoService;

    @Resource
    private UserService userService;
    @Resource
    private InterfaceInfoService interfaceInfoService;

    @Resource
    private InterfaceInfoChargeService interfaceInfoChargeService;
    // region 增删改查

    /**
     * 创建
     *
     * @param userInterfaceInfoAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> adduserInterfaceInfo(@RequestBody UserInterfaceInfoAddRequest userInterfaceInfoAddRequest, HttpServletRequest request) {
        log.info(userInterfaceLog+"增加用户接口-进入接口....");
        if (userInterfaceInfoAddRequest == null) {
            log.error(userInterfaceLog+"增加用户接口-参数错误");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserInterfaceInfo userInterfaceInfo = new UserInterfaceInfo();
        BeanUtils.copyProperties(userInterfaceInfoAddRequest, userInterfaceInfo);
        userInterfaceInfoService.validUserInterfaceInfo(userInterfaceInfo, true);
        log.info("用户接口业务层-判断用户接口信息是否合法-结束业务层....");
        User loginUser = userService.getLoginUser(request);
        log.info(userInterfaceLog+"增加用户接口-获取当前登录态信息");
        userInterfaceInfo.setUserId(loginUser.getId());
        log.info(userInterfaceLog+"增加用户接口-将对象插入数据库");
        boolean result = userInterfaceInfoService.save(userInterfaceInfo);
        if (!result) {
            log.error(userInterfaceLog+"增加用户接口-插入失败");
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        long newuserInterfaceInfoId = userInterfaceInfo.getId();
        log.info(userInterfaceLog+"增加用户接口-结束接口，返回用户接口信息id....");
        return ResultUtils.success(newuserInterfaceInfoId);

    }

    /**
     * 删除
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteuserInterfaceInfo(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        log.info(userInterfaceLog+"删除用户接口信息-进入接口....");
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            log.error(userInterfaceLog+"删除用户接口信息-用户请求不存在或者用户id不合法");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getLoginUser(request);
        log.info(userInterfaceLog+"删除用户接口信息-获取当前用户登录态信息");
        long id = deleteRequest.getId();
        // 判断是否存在
        UserInterfaceInfo oldInterfaceInfo = userInterfaceInfoService.getById(id);
        log.info(userInterfaceLog+"删除用户接口信息-根据id获取用户接口信息");
        if (oldInterfaceInfo == null) {
            log.error(userInterfaceLog+"删除用户接口信息-这个id的用户接口不存在");
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 仅本人或管理员可删除
        if (!oldInterfaceInfo.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            log.error(userInterfaceLog+"删除用户接口信息-不是本人也不是管理员");
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean b = userInterfaceInfoService.removeById(id);
        log.info(userInterfaceLog+"删除用户接口信息-结束接口....");
        return ResultUtils.success(b);
    }

    /**
     * 更新（仅管理员）
     *
     * @param userInterfaceInfoUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateuserInterfaceInfo(@RequestBody InterfaceInfoUpdateRequest userInterfaceInfoUpdateRequest
    ,HttpServletRequest request) {
        log.info(userInterfaceLog+"更新用户接口信息-进入接口....");
        if (userInterfaceInfoUpdateRequest == null || userInterfaceInfoUpdateRequest.getId() <= 0) {
            log.info(userInterfaceLog+"更新用户接口信息-请求为空或者id不合法");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserInterfaceInfo userInterfaceInfo = new UserInterfaceInfo();
        BeanUtils.copyProperties(userInterfaceInfoUpdateRequest, userInterfaceInfo);
        // 参数校验
        userInterfaceInfoService.validUserInterfaceInfo(userInterfaceInfo, false);
        log.info(userInterfaceLog+"更新用户接口信息-参数校验");
        User user = userService.getLoginUser(request);
        log.info(userInterfaceLog+"更新用户接口信息-获取当前登录态");
        long id = userInterfaceInfoUpdateRequest.getId();
        // 判断是否存在
        UserInterfaceInfo oldInterfaceInfo = userInterfaceInfoService.getById(id);
        log.info(userInterfaceLog+"更新用户接口信息-根据id查询当前用户接口信息");
        // 仅本人或管理员可修改
        if (!oldInterfaceInfo.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            log.error(userInterfaceLog+"更新用户接口信息-不是本人和管理员");
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        boolean result = userInterfaceInfoService.updateById(userInterfaceInfo);
        log.info(userInterfaceLog+"更新用户接口信息-根据id在数据库中更新用户接口表");
        log.info(userInterfaceLog+"更新用户接口信息-结束接口....");
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<UserInterfaceInfo> getuserInterfaceInfoVOById(long id, HttpServletRequest request) {
        log.info(userInterfaceLog+"根据id获取用户接口信息-进入接口....");
        if (id <= 0) {
            log.error(userInterfaceLog+"根据id获取用户接口信息-id不合法");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserInterfaceInfo userInterfaceInfo = userInterfaceInfoService.getById(id);
        log.info(userInterfaceLog+"根据id获取用户接口信息-结束接口....");
        return ResultUtils.success(userInterfaceInfo);

    }

    /**
     * 分页获取列表（封装类）
     * @param userInterfaceInfoQueryRequest
     * @return
     */
    @GetMapping("/list")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<List<UserInterfaceInfo>> listInterfaceInfo(InterfaceInfoQueryRequest userInterfaceInfoQueryRequest) {
        log.info(userInterfaceLog+"获取列表-进入接口....");
        UserInterfaceInfo userInterfaceInfoQuery = new UserInterfaceInfo();
        if (userInterfaceInfoQueryRequest != null) {
            log.info(userInterfaceLog+"获取列表-参数不是全为空，将参数赋值给新创建的用户接口对象");
            BeanUtils.copyProperties(userInterfaceInfoQueryRequest, userInterfaceInfoQuery);
        }
        QueryWrapper<UserInterfaceInfo> queryWrapper = new QueryWrapper<>(userInterfaceInfoQuery);
        log.info(userInterfaceLog+"获取列表-根据请求参数用列表查询业务层开始......");
        List<UserInterfaceInfo> userInterfaceInfoList = userInterfaceInfoService.list(queryWrapper);
        log.info(userInterfaceLog+"获取列表-列表查询业务层结束....");
        log.info(userInterfaceLog+"获取列表-结束接口....");
        return ResultUtils.success(userInterfaceInfoList);
    }


    /**
     * 分页获取列表
     *
     * @param userInterfaceInfoQueryRequest
     * @param request
     * @return
     */
    @GetMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<UserInterfaceInfo>> listInterfaceInfoByPage(InterfaceInfoQueryRequest userInterfaceInfoQueryRequest, HttpServletRequest request) {
        log.info(userInterfaceLog+"分页获取列表-进入接口.....");
        if (userInterfaceInfoQueryRequest == null) {
            log.error(userInterfaceLog+"分页获取列表-请求参数为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserInterfaceInfo userInterfaceInfoQuery = new UserInterfaceInfo();
        BeanUtils.copyProperties(userInterfaceInfoQueryRequest, userInterfaceInfoQuery);
        long current = userInterfaceInfoQueryRequest.getCurrent();
        long size = userInterfaceInfoQueryRequest.getPageSize();
        String sortField = userInterfaceInfoQueryRequest.getSortField();
        String sortOrder = userInterfaceInfoQueryRequest.getSortOrder();
        // 限制爬虫
        if (size > 50) {
            log.info(userInterfaceLog+"分页获取列表-页面大小不能超过50");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<UserInterfaceInfo> queryWrapper = new QueryWrapper<>(userInterfaceInfoQuery);
        queryWrapper.orderBy(StringUtils.isNotBlank(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        Page<UserInterfaceInfo> userInterfaceInfoPage = userInterfaceInfoService.page(new Page<>(current, size), queryWrapper);
        log.info(userInterfaceLog+"分页获取列表-更具请求参数分页查询");
        log.info(userInterfaceLog+"分页获取列表-结束接口.....");
        return ResultUtils.success(userInterfaceInfoPage);
    }

    /**
     * 我拥有的接口
     * @param userId
     * @param request
     * @return
     */
    @GetMapping("/list/userId")
    public BaseResponse<List<UserInterfaceInfoVO>> getInterfaceInfoByUserId(@RequestParam Long userId, HttpServletRequest request) {
        log.info(userInterfaceLog+"查询我拥有的接口列表-进入接口.....");
        List<UserInterfaceInfoVO> list=userInterfaceInfoService.getInterfaceInfoByUserId(userId);
        log.info(userInterfaceLog+"查询我拥有的接口列表-根据用户id查询接口列表");
        //根据vo中的接口id查询每个id的详细描述
        List<UserInterfaceInfoVO> result=new ArrayList<>();
        log.info(userInterfaceLog+"查询我拥有的接口列表-遍历所有查询到的接口");
        for(UserInterfaceInfoVO vo:list){
            Long interfaceInfoId = vo.getInterfaceInfoId();
            InterfaceInfo interfaceInfo = interfaceInfoService.getById(interfaceInfoId);
            BeanUtils.copyProperties(interfaceInfo,vo);
            vo.setInterfaceStatus(interfaceInfo.getStatus());
            result.add(vo);
        }
        log.info(userInterfaceLog+"查询我拥有的接口列表-结束接口.....");
        return ResultUtils.success(result);
    }
    // endregion
    /**
     * 给用户分配免费的调用次数
     * @param updateUserInterfaceInfoDTO
     * @param request
     * @return
     */
    @PostMapping("/get/free")
    public BaseResponse<Boolean> getFreeInterfaceCount(@RequestBody UpdateUserInterfaceInfoDTO updateUserInterfaceInfoDTO, HttpServletRequest request) {
        log.info(userInterfaceLog+"给用户分配免费的调用次数-进入接口.....");
        Long interfaceInfoId = updateUserInterfaceInfoDTO.getInterfaceInfoId();
        Long userId = updateUserInterfaceInfoDTO.getUserId();
        Long lockNum = updateUserInterfaceInfoDTO.getLockNum();
        if (interfaceInfoId == null || userId == null || lockNum == null) {
            log.error(userInterfaceLog+"给用户分配免费的调用次数-接口id/用户id/请求分配次数为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (lockNum > 100) {
            log.error(userInterfaceLog+"给用户分配免费的调用次数-一次性获取的次数太多了");
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "您一次性获取的次数太多了");
        }
        synchronized (userId) {
            User loginUser = userService.getLoginUser(request);
            log.info(userInterfaceLog+"给用户分配免费的调用次数-获取当前登录态");
            if (!userId.equals(loginUser.getId())) {
                log.error(userInterfaceLog+"给用户分配免费的调用次数-没有权限");
                throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
            }
            long interfaceCharging = interfaceInfoChargeService.count(new QueryWrapper<InterfaceInfoCharge>().eq("interfaceInfoId", interfaceInfoId));
            if (interfaceCharging > 0) {
                log.error(userInterfaceLog+"给用户分配免费的调用次数-这个是付费接口");
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "这个是付费接口噢!");
            }
            UserInterfaceInfo one = userInterfaceInfoService.getOne(new QueryWrapper<UserInterfaceInfo>().eq("userId", userId).eq("interfaceInfoId", interfaceInfoId));
            if (one != null && one.getLeftNum() >= 1000) {
                log.error(userInterfaceLog+"给用户分配免费的调用次数-您获取的次数太多了");
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "您获取的次数太多了");
            }
            boolean b = userInterfaceInfoService.updateUserInterfaceInfo(updateUserInterfaceInfoDTO);
            log.info(userInterfaceLog+"给用户分配免费的调用次数-更新用户接口信息到数据库");
            log.info(userInterfaceLog+"给用户分配免费的调用次数-结束接口.....");
            return ResultUtils.success(b);
        }
    }

}
